<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Exceptions\ThrottleRequestsException;
use Illuminate\Http\Response;
use Illuminate\Routing\Middleware\ThrottleRequests;

class UserThrottleRequests extends ThrottleRequests
{
    /**
     * Handle an incoming request.
     *
     * @param mixed $request
     * @param Closure $next
     * @param int $maxAttempts
     * @param int $decayMinutes
     * @param string $prefix
     * @return HttpResponseException|ThrottleRequestsException|\Symfony\Component\HttpFoundation\Response
     */
    public function handle($request, Closure $next, $maxAttempts = 3000, $decayMinutes = 60, $prefix = ''): HttpResponseException|ThrottleRequestsException|\Symfony\Component\HttpFoundation\Response
    {
        $key = $this->resolveRequestSignature($request);
        $maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts);
        if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
            return $this->buildException($request, $key, $maxAttempts);
        }
        //去掉 `* 60` 限制秒级,加上去限制分钟,要限制其他单位，可以自己算的
        $this->limiter->hit($key, $decayMinutes);//默认60秒60次
        //$this->limiter->hit($key, $decayMinutes * 60);
        $response = $next($request);
        return $this->addHeaders($response, $maxAttempts, $this->calculateRemainingAttempts($key, $maxAttempts));
    }

    protected function buildException($request, $key, $maxAttempts, $responseCallback = null): HttpResponseException|ThrottleRequestsException|\Symfony\Component\HttpFoundation\Response
    {
        $retryAfter = $this->limiter->availableIn($key);
        //要返回的数据
        return $this->addHeaders(new Response(json_encode([
            'code' => 441,
            'message' => __('errorCode.441'),
            'timestamp' => now()->format('Y-m-d H:i:s.u'),
        ], 320), 200), $maxAttempts, $this->calculateRemainingAttempts($key, $maxAttempts, $retryAfter), $retryAfter);
    }

    protected function addHeaders(\Symfony\Component\HttpFoundation\Response $response, $maxAttempts, $remainingAttempts, $retryAfter = null): \Symfony\Component\HttpFoundation\Response
    {
        $response->headers->add(['Content-Type' => 'application/json;charset=utf-8']);
        return parent::addHeaders($response, $maxAttempts, $remainingAttempts, $retryAfter);
    }
}
